#!/usr/bin/env python
"""
百家乐系统API处理程序
提供HTTP API接口用于前端与后端通信
"""
import json
from flask import Flask, request, jsonify
from flask_cors import CORS
from models import Simulation
import utils

app = Flask(__name__)
# 增强CORS配置,允许所有来源
CORS(app, resources={r"/api/*": {"origins": "*", "supports_credentials": False}})

@app.route('/api/simulations', methods=['GET'])
def get_simulations():
    """获取历史模拟列表"""
    simulations = Simulation.get_all(limit=20)
    return jsonify([sim.to_dict() for sim in simulations])

@app.route('/api/simulations/run', methods=['POST'])
def run_simulation():
    """运行新的模拟"""
    try:
        data = request.json
        
        # 详细记录传入参数
        print(f"收到模拟请求，参数: {data}")
        
        # 提取参数
        strategy_name = data.get('strategy_name', '默认策略')
        max_rounds = min(int(data.get('max_rounds', 1000)), 5000)  # 限制最大局数，实际会在牌不足时提前结束
        deck_seed = data.get('deck_seed')
        parameters = data.get('parameters', {})
        
        # 检查必要参数
        if 'strategy_table_id' not in parameters:
            print("缺少必要参数: strategy_table_id")
            return jsonify({"error": "缺少必要参数: strategy_table_id"}), 400
        
        # 预先验证策略表是否存在
        strategy_table_id = parameters.get('strategy_table_id')
        from models import BetStrategyTable
        strategy_table = BetStrategyTable.get_by_id(strategy_table_id)
        if not strategy_table:
            print(f"策略表不存在，ID: {strategy_table_id}")
            return jsonify({"error": f"策略表不存在，ID: {strategy_table_id}"}), 404
        
        # 运行模拟
        result = utils.run_simulation(
            strategy_name=strategy_name,
            deck_seed=deck_seed,
            max_rounds=max_rounds,
            parameters=parameters
        )
        
        # 检查模拟结果
        if result is None:
            print("模拟执行返回空结果")
            return jsonify({"error": "模拟执行失败，请检查服务器日志"}), 500
        
        print(f"模拟完成，ID: {result.get('simulation_id')}")
        return jsonify(result)
    except Exception as e:
        import traceback
        print(f"模拟执行异常: {str(e)}")
        traceback.print_exc()  # 打印完整堆栈跟踪
        return jsonify({"error": str(e)}), 500

@app.route('/api/simulation/<int:simulation_id>', methods=['GET'])
def get_simulation(simulation_id):
    """获取模拟详情"""
    try:
        # 使用utils中的函数获取完整模拟结果
        result = utils.get_simulation_results(simulation_id)
        
        if result is None:
            return jsonify({"error": "未找到该模拟记录"}), 404
            
        return jsonify(result)
    except Exception as e:
        return str(e), 400

@app.route('/api/history', methods=['GET'])
def get_history():
    """获取最近的游戏历史记录"""
    try:
        # 获取查询参数
        limit = request.args.get('limit', default=10, type=int)
        
        # 使用utils中的函数获取历史记录
        history = utils.get_history(limit=limit)
        
        return jsonify(history)
    except Exception as e:
        return jsonify({"error": str(e)}), 500

@app.route('/api/cards-status', methods=['GET'])
def get_cards_status():
    """获取当前牌组状态"""
    try:
        # 默认的牌组状态响应
        status = {
            "total_cards": 416,  # 8副牌 = 8 * 52 = 416张
            "cards_dealt": 0,
            "remaining_cards": 416,
            "remaining_deals": 208,  # 估计每局平均用2张牌
            "need_shuffle": False
        }
        
        return jsonify(status)
    except Exception as e:
        return jsonify({"error": str(e)}), 500

@app.route('/api/clear-simulations', methods=['POST'])
def clear_all_simulations():
    """清空所有模拟记录"""
    try:
        result = utils.clear_all_simulations()
        if result:
            return jsonify({"message": "所有模拟记录已清空"}), 200
        else:
            return jsonify({"error": "清空模拟记录失败"}), 500
    except Exception as e:
        return jsonify({"error": str(e)}), 500
        
@app.route('/api/clear-simulation/<int:simulation_id>', methods=['POST'])
def clear_simulation(simulation_id):
    """清空特定ID的模拟记录"""
    try:
        result = utils.clear_simulation(simulation_id)
        if result:
            return jsonify({"message": f"模拟记录 {simulation_id} 已清空"}), 200
        else:
            return jsonify({"message": f"未找到ID为 {simulation_id} 的模拟记录"}), 404
    except Exception as e:
        return jsonify({"error": str(e)}), 500

@app.route('/api/statistics', methods=['GET'])
def get_statistics():
    """获取游戏统计数据"""
    try:
        stats = utils.get_statistics()
        if stats:
            response = jsonify(stats)
            print(response)
            # 添加CORS头部不再需要，已经由CORS扩展自动处理
            return response
        else:
            return jsonify({"error": "Failed to fetch statistics"}), 500
    except Exception as e:
        return jsonify({"error": str(e)}), 500

@app.route('/api/bet-strategies', methods=['GET'])
def get_bet_strategies():
    """获取所有下注策略"""
    try:
        conn = utils.psycopg2.connect(**utils.DB_CONFIG)
        cursor = conn.cursor(cursor_factory=utils.RealDictCursor)
        
        cursor.execute('SELECT * FROM bet_strategies ORDER BY id ASC')
        strategies = cursor.fetchall()
        
        # 处理JSON字段
        for strategy in strategies:
            strategy['level1'] = json.loads(strategy['level1'])
            strategy['level2'] = json.loads(strategy['level2'])
            strategy['level3'] = json.loads(strategy['level3'])
        
        return jsonify(strategies)
    except Exception as e:
        return jsonify({"error": str(e)}), 500
    finally:
        if cursor:
            cursor.close()
        if conn:
            conn.close()

@app.route('/api/bet-strategies/default', methods=['GET'])
def get_default_bet_strategy():
    """获取默认下注策略"""
    try:
        strategy = utils.get_bet_strategy()
        return jsonify(strategy)
    except Exception as e:
        return jsonify({"error": str(e)}), 500

@app.route('/api/bet-strategies/<string:name>', methods=['GET'])
def get_bet_strategy_by_name(name):
    """获取指定名称的下注策略"""
    try:
        strategy = utils.get_bet_strategy(name)
        if not strategy or strategy['name'] != name:
            return jsonify({"error": f"未找到名为'{name}'的策略"}), 404
        return jsonify(strategy)
    except Exception as e:
        return jsonify({"error": str(e)}), 500

@app.route('/api/bet-strategies', methods=['POST'])
def create_bet_strategy():
    """创建新的下注策略"""
    try:
        data = request.json
        
        # 检查必须的字段
        required_fields = ['name', 'level1', 'level2', 'level3']
        for field in required_fields:
            if field not in data:
                return jsonify({"error": f"缺少必要字段: {field}"}), 400
        
        # 检查注码是否为数组
        for level in ['level1', 'level2', 'level3']:
            if not isinstance(data[level], list) or not all(isinstance(x, (int, float)) for x in data[level]):
                return jsonify({"error": f"{level}必须是一个数字数组"}), 400
        
        # 保存策略
        success = utils.save_bet_strategy(data)
        
        if success:
            return jsonify({"message": f"策略'{data['name']}'保存成功"}), 201
        else:
            return jsonify({"error": "保存策略失败"}), 500
    except Exception as e:
        return jsonify({"error": str(e)}), 500

@app.route('/api/bet-strategies/<string:name>', methods=['PUT'])
def update_bet_strategy(name):
    """更新指定名称的下注策略"""
    try:
        data = request.json
        
        # 确保名称匹配
        data['name'] = name
        
        # 检查必须的字段
        required_fields = ['level1', 'level2', 'level3']
        for field in required_fields:
            if field not in data:
                return jsonify({"error": f"缺少必要字段: {field}"}), 400
        
        # 检查注码是否为数组
        for level in ['level1', 'level2', 'level3']:
            if not isinstance(data[level], list) or not all(isinstance(x, (int, float)) for x in data[level]):
                return jsonify({"error": f"{level}必须是一个数字数组"}), 400
        
        # 检查策略是否存在
        existing = utils.get_bet_strategy(name)
        if not existing or existing['name'] != name:
            return jsonify({"error": f"未找到名为'{name}'的策略"}), 404
        
        # 保存策略
        success = utils.save_bet_strategy(data)
        
        if success:
            return jsonify({"message": f"策略'{name}'更新成功"})
        else:
            return jsonify({"error": "更新策略失败"}), 500
    except Exception as e:
        return jsonify({"error": str(e)}), 500

@app.route('/api/bet-strategies/<string:name>', methods=['DELETE'])
def delete_bet_strategy(name):
    """删除指定名称的下注策略"""
    try:
        conn = utils.psycopg2.connect(**utils.DB_CONFIG)
        cursor = conn.cursor()
        
        # 检查是否为默认策略
        cursor.execute("SELECT is_default FROM bet_strategies WHERE name = %s", (name,))
        result = cursor.fetchone()
        
        if not result:
            return jsonify({"error": f"未找到名为'{name}'的策略"}), 404
        
        is_default = result[0]
        
        if is_default:
            return jsonify({"error": "不能删除默认策略"}), 400
        
        # 执行删除
        cursor.execute("DELETE FROM bet_strategies WHERE name = %s", (name,))
        
        if cursor.rowcount > 0:
            conn.commit()
            return jsonify({"message": f"策略'{name}'已删除"})
        else:
            return jsonify({"error": "删除策略失败"}), 500
    except Exception as e:
        if conn:
            conn.rollback()
        return jsonify({"error": str(e)}), 500
    finally:
        if cursor:
            cursor.close()
        if conn:
            conn.close()

@app.route('/api/bet-strategies/<string:name>/set-default', methods=['POST'])
def set_default_strategy(name):
    """设置默认下注策略"""
    try:
        conn = utils.psycopg2.connect(**utils.DB_CONFIG)
        cursor = conn.cursor()
        
        # 先检查策略是否存在
        cursor.execute('SELECT COUNT(*) FROM bet_strategies WHERE name = %s', (name,))
        count = cursor.fetchone()[0]
        
        if count == 0:
            return jsonify({"error": f"未找到名为'{name}'的策略"}), 404
        
        # 先将所有策略设为非默认
        cursor.execute('UPDATE bet_strategies SET is_default = FALSE')
        
        # 再将指定策略设为默认
        cursor.execute('UPDATE bet_strategies SET is_default = TRUE WHERE name = %s', (name,))
        
        conn.commit()
        return jsonify({"message": f"已将'{name}'设为默认策略"}), 200
    except Exception as e:
        if conn:
            conn.rollback()
        return jsonify({"error": str(e)}), 500
    finally:
        if cursor:
            cursor.close()
        if conn:
            conn.close()

# 下注策略表相关API
@app.route('/api/bet-strategy-tables', methods=['GET'])
def get_bet_strategy_tables():
    """获取所有下注策略表"""
    try:
        from models import BetStrategyTable
        strategy_tables = BetStrategyTable.get_all()
        return jsonify([st.to_dict() for st in strategy_tables])
    except Exception as e:
        return jsonify({"error": str(e)}), 500

@app.route('/api/bet-strategy-tables/default', methods=['GET'])
def get_default_bet_strategy_table():
    """获取默认下注策略表"""
    try:
        from models import BetStrategyTable
        strategy_table = BetStrategyTable.get_default()
        if not strategy_table:
            return jsonify({"error": "没有找到默认策略表"}), 404
        return jsonify(strategy_table.to_dict())
    except Exception as e:
        return jsonify({"error": str(e)}), 500

@app.route('/api/bet-strategy-tables/<int:table_id>', methods=['GET'])
def get_bet_strategy_table(table_id):
    """获取指定ID的下注策略表"""
    try:
        from models import BetStrategyTable
        strategy_table = BetStrategyTable.get_by_id(table_id)
        if not strategy_table:
            return jsonify({"error": f"未找到ID为{table_id}的策略表"}), 404
        return jsonify(strategy_table.to_dict())
    except Exception as e:
        return jsonify({"error": str(e)}), 500

@app.route('/api/bet-strategy-tables/by-name/<string:name>', methods=['GET'])
def get_bet_strategy_table_by_name(name):
    """获取指定名称的下注策略表"""
    try:
        from models import BetStrategyTable
        strategy_table = BetStrategyTable.get_by_name(name)
        if not strategy_table:
            return jsonify({"error": f"未找到名为'{name}'的策略表"}), 404
        return jsonify(strategy_table.to_dict())
    except Exception as e:
        return jsonify({"error": str(e)}), 500

@app.route('/api/bet-strategy-tables', methods=['POST'])
def create_bet_strategy_table():
    """创建新的下注策略表"""
    try:
        # post过来的实际数据是：{"name":"常规注码","description":"赢了不加注，输了加注，加注不升级","strategy_content":"+1000:1000\n-1000:1100\n-1100:1300\n-1300:1700\n-1700:1000","is_default":true}
        data = request.json
        
        # 检查必须的字段
        required_fields = ['name', 'strategy_content']
        for field in required_fields:
            if field not in data:
                return jsonify({"error": f"缺少必要字段: {field}"}), 400
        
        # 检查策略内容是否为字符串
        if not isinstance(data['strategy_content'], str):
            return jsonify({"error": "strategy_content必须是字符串格式"}), 400
            
        # 验证策略内容格式
        try:
            from models import BetStrategyTable
            # 尝试解析策略内容
            test_table = BetStrategyTable(strategy_content=data['strategy_content'])
            parsed_rules = test_table.get_table_data()
            
            # 检查是否成功解析出规则
            if not parsed_rules:
                return jsonify({"error": "策略内容格式错误，无法解析出有效规则"}), 400
                
        except Exception as e:
            return jsonify({"error": f"策略内容解析失败: {str(e)}"}), 400
        
        # 创建并保存策略表
        strategy_table = BetStrategyTable(
            name=data['name'],
            description=data.get('description', ''),
            strategy_content=data['strategy_content'],
            is_default=data.get('is_default', False)
        )
        
        success = strategy_table.save()
        
        if success:
            return jsonify({
                "message": f"策略表'{data['name']}'保存成功",
                "id": strategy_table.id
            }), 201
        else:
            return jsonify({"error": "保存策略表失败"}), 500
    except Exception as e:
        return jsonify({"error": str(e)}), 500

@app.route('/api/bet-strategy-tables/<int:table_id>', methods=['PUT'])
def update_bet_strategy_table(table_id):
    """更新指定ID的下注策略表"""
    try:
        from models import BetStrategyTable
        data = request.json
        
        # 获取现有策略表
        strategy_table = BetStrategyTable.get_by_id(table_id)
        if not strategy_table:
            return jsonify({"error": f"未找到ID为{table_id}的策略表"}), 404
        
        # 更新字段
        if 'name' in data:
            strategy_table.name = data['name']
        if 'description' in data:
            strategy_table.description = data['description']
        if 'strategy_content' in data:
            if not isinstance(data['strategy_content'], str):
                return jsonify({"error": "策略内容必须是字符串格式"}), 400
                
            # 验证策略内容格式
            try:
                # 尝试解析策略内容
                test_table = BetStrategyTable(strategy_content=data['strategy_content'])
                parsed_rules = test_table.get_table_data()
                
                # 检查是否成功解析出规则
                if not parsed_rules:
                    return jsonify({"error": "策略内容格式错误，无法解析出有效规则"}), 400
                    
            except Exception as e:
                return jsonify({"error": f"策略内容解析失败: {str(e)}"}), 400
                
            strategy_table.strategy_content = data['strategy_content']
        
        if 'is_default' in data:
            strategy_table.is_default = data['is_default']
        
        # 保存更新
        success = strategy_table.save()
        
        if success:
            return jsonify({
                "message": f"策略表'{strategy_table.name}'更新成功",
                "id": strategy_table.id
            }), 200
        else:
            return jsonify({"error": "更新策略表失败"}), 500
    except Exception as e:
        return jsonify({"error": str(e)}), 500

@app.route('/api/bet-strategy-tables/<int:table_id>', methods=['DELETE'])
def delete_bet_strategy_table(table_id):
    """删除指定ID的下注策略表"""
    try:
        from models import BetStrategyTable
        
        # 检查策略表是否存在
        strategy_table = BetStrategyTable.get_by_id(table_id)
        if not strategy_table:
            return jsonify({"error": f"未找到ID为{table_id}的策略表"}), 404
        
        # 执行删除
        success = BetStrategyTable.delete(table_id)
        
        if success:
            return jsonify({"message": f"策略表'{strategy_table.name}'删除成功"}), 200
        else:
            return jsonify({"error": "删除策略表失败，可能是默认策略无法删除"}), 400
    except Exception as e:
        return jsonify({"error": str(e)}), 500

@app.route('/api/bet-strategy-tables/<int:table_id>/set-default', methods=['POST'])
def set_default_strategy_table(table_id):
    """设置指定ID的策略表为默认"""
    try:
        from models import BetStrategyTable
        
        # 获取策略表
        strategy_table = BetStrategyTable.get_by_id(table_id)
        if not strategy_table:
            return jsonify({"error": f"未找到ID为{table_id}的策略表"}), 404
        
        # 设置为默认并保存
        strategy_table.is_default = True
        success = strategy_table.save()
        
        if success:
            return jsonify({"message": f"已将'{strategy_table.name}'设为默认策略表"}), 200
        else:
            return jsonify({"error": "设置默认策略表失败"}), 500
    except Exception as e:
        return jsonify({"error": str(e)}), 500

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5003, debug=True) 